package local.pt.iscte.dcti.pa.model;

import com.eexcel.workbench.EvaluateContributionsHandler;
import com.eexcel.workbench.IFormula;

import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;

/**
 * Handles the extension contributions
 * 
 * @author Simao Fernandes
 * @version %I%, %G%
 * @since 1.0
 */
public class FormulaHandler_dep {
	
	private static final String IFORMULA_ID = "com.eexcel.workbench.formula";
	private IConfigurationElement[] config;
	
	public FormulaHandler_dep() {
		EvaluateContributionsHandler handler = new EvaluateContributionsHandler();
		IExtensionRegistry reg = Platform.getExtensionRegistry();
		handler.execute(reg);
		
		config = Platform.getExtensionRegistry().getConfigurationElementsFor(IFORMULA_ID);
	}
	
	/**
	 * Result
	 */
	private static int result;
	/**
	 * Gets the result
	 * 
	 * @return Result
	 */
	private static int getResult() {
		return result;
	}
	/**
	 * Set the result
	 * 
	 * @param result
	 *            Result
	 */
	private static void setResult(int result) {
		FormulaHandler_dep.result = result;
	}
	/**
	 * Operand
	 */
	private static int operand;
	/**
	 * Gets the operand
	 * 
	 * @return Operand
	 */
	private static int getOperand() {
		return operand;
	}
	/**
	 * Sets the operand
	 * 
	 * @param operand
	 *            Operand
	 */
	private static void setOperand(int operand) {
		FormulaHandler_dep.operand = operand;
	}
	
	private static String[] functions;
	
	private static String[] getFunctions() {
		return functions;
	}
	
	private static void setFunctions(String[] functions) {
		FormulaHandler_dep.functions = functions;
	}
	
	private static String currentFunction;
	/**
	 * Gets the currentFunction
	 * @return Current function
	 */
	private static String getCurrentFunction() {
		return currentFunction;
	}

	/**
	 * Set the current function
	 * @param currentFunc Current function
	 */
	private static void setCurrentFunction(String currentFunc) {
		FormulaHandler_dep.currentFunction = currentFunc;
	}

	
	/**
	 * Gets the function names provided by the plug-in 
	 * @return Function names
	 */
	public String[] getFunctionNames ()
	{

		try {
			for (IConfigurationElement e : config) {
				final Object o = e.createExecutableExtension("class");
				if (o instanceof IFormula) {
					getNames(o);
				}
			}
		} catch (org.eclipse.core.runtime.CoreException e) {
			e.printStackTrace();
		}
		
		return getFunctions();
	}
	
	/**
	 * Gets the names of the formulas provided by the plug-ins
	 * @param o Extension instance
	 */
	private static void getNames(final Object o)
	{
		org.eclipse.core.runtime.ISafeRunnable runnable = new org.eclipse.core.runtime.ISafeRunnable() {
			@Override
			public void handleException(Throwable exception) {
				System.out.println("Exception in client");
			}

			@Override
			public void run() throws Exception {
				String[] functions = ((IFormula) o).getFunctions();
				setFunctions(functions);
			}
		};
		org.eclipse.core.runtime.SafeRunner.run(runnable);
	}
	
	
	/**
	 * Applies the formula
	 * @param functionName Name of the function that defines the formula
	 * @param operand Operand
	 * @return Result
	 */
	public int doIt(String functionName, int operand) {

		setOperand(operand);
		setCurrentFunction(functionName);
		
		try {
			for (IConfigurationElement e : config) {
				final Object o = e.createExecutableExtension("class");
				if (o instanceof IFormula) {
					executeExtension(o);
				}
			}
		} catch (org.eclipse.core.runtime.CoreException e) {
			// TODO: handle exception
		}
		return getResult();
	}

	/**
	 * Executes the extension
	 * @param o Extension instance
	 */
	private static void executeExtension(final Object o) {

		org.eclipse.core.runtime.ISafeRunnable runnable = new org.eclipse.core.runtime.ISafeRunnable() {
			@Override
			public void handleException(Throwable exception) {
				System.out.println("Exception in client");
			}

			@Override
			public void run() throws Exception {
				int fib = ((IFormula) o).calculate(getCurrentFunction(), getOperand());
				setResult(fib);
			}
		};
		org.eclipse.core.runtime.SafeRunner.run(runnable);
	}
}
